<template>
  <div class="app-container" style="display: flex; flex-direction: column; height: calc(80vh)">
    <!-- Header 区域 -->
    <div class="header">
      <button class="nav-button" @click="goToPreviousStep">上一步</button>
      <div class="steps-container">
        <div v-for="(step, index) in steps" :key="index" :class="['step-box', { active: index === 1 }]">
          {{ step }}
        </div>
      </div>
      <button class="nav-button" @click="goToNextStep">下一步</button>
    </div>
    <!-- 主内容区域，分为左侧的侧边栏和右侧的主工作区 -->
    <div class="content" style="display: flex; flex: 1; overflow: hidden">
      <!-- 左侧侧边栏，占约1/5宽度 -->
      <aside class="sidebar">
        <div v-for="(memo, index) in memos" :key="index" class="memo-item" @click="handleMemoClick(memo)">
          <!-- Name单独在顶部 -->
          <div class="memo-name">{{ memo.name }}</div>
          <!-- 下方分为左右两部分，Status在左，Button在右 -->
          <div class="memo-content">
            <div class="memo-status">状态：{{ memo.status }}</div>
            <button class="memo-button" @click.stop="handleMemo(memo)">{{ memo.button }}</button>
          </div>
        </div>
      </aside>
      <OutMaterial_Information ref="OutMaterialWindowRef" />

      <!-- 右侧主工作区 -->
      <div class="flow-container" style="position: relative; flex: 1; overflow: hidden">
        <!-- 可根据需求调整 Structure_Information 的位置 -->
        <Structure_Information ref="InformationWindowRef" />
        <!-- 删除模态框 -->
        <div v-if="isModalDelOpen" class="modal">
          <div class="modal-content">
            <h4>确定要删除吗</h4>
            <button @click="deleteNode">确定</button>
            <button @click="closeDelModal">取消</button>
          </div>
        </div>

        <!-- VueFlow 工作区域 -->
        <VueFlow
          v-model:nodes="nodes"
          v-model:edges="edges"
          fit-view-on-init
          class="confirm-flow"
          :default-zoom="1.5"
          :min-zoom="0.2"
          :max-zoom="4"
          @node-click="onNodeClick"
          style="height: 100%"
        >
          <Background color="white" />
          <!-- 自定义节点模板 -->
          <template #node-productNode_homeMade="props">
            <productNode_homeMade :id="props.id" :data="props.data" @toolbar-action="handleToolbarAction" />
          </template>
          <template #node-productNode_outBuy="props">
            <productNode_outBuy :id="props.id" :data="props.data" @toolbar-action="handleToolbarAction" />
          </template>
          <template #node-productNode_outBuy1="props">
            <productNode_outBuy1 :id="props.id" :data="props.data" @toolbar-action="handleToolbarAction" />
          </template>
        </VueFlow>
      </div>
    </div>
  </div>
</template>

<script lang="tsx" setup name="useProtable">
import { onMounted, ref } from "vue";
import { VueFlow, type Node, type Edge, MarkerType } from "@vue-flow/core";
import { Background } from "@vue-flow/background";
import { ProductTree, Material } from "@/api/interface";
import { computed } from "vue";
import { useRouter, useRoute } from "vue-router";
import productNode_homeMade from "./components/productNode_homeMade.vue";
import productNode_outBuy from "./components/productNode_outBuy.vue";
import productNode_outBuy1 from "./components/productNode_outbuy1.vue";
import Structure_Information from "./components/structure_Information.vue";
import { ElMessage, ElMessageBox } from "element-plus";
import OutMaterial_Information from "./components/outMaterial_Information.vue";
import { calculateNodeCoordinates, assignNodeIndices } from "@/utils/nodePositionHandler";
import axios from "axios";
import { useTabsStore } from "@/stores/modules/tabs";
const tabStore = useTabsStore();
interface Memo {
  name: string;
  status: string;
  button: string;
  materialId: number;
}
const baseUrl = import.meta.env.VITE_BASE_URL;
const materialList = ref<Partial<Material.ResMaterial>[]>([]);
const steps = ref(["产品碳排放源分析", "外购零部件碳排放值收集", "产品生产装配碳排放值收集"]);
const router = useRouter();
const route = useRoute();
/**当前指定的project编号 */
const currentProjectId = ref("-1");
/**项目对应产品 */
const product = ref();
/**产品结构树 */
const tree = ref<Partial<ProductTree.ResProduct_Tree>>();
/**实际使用的PCF请求列表 */
// const fetchedPCFrequestList = ref<Partial<PCFrequest.ResPCFrequest>[]>([]);
/**产品名称 */
const rootname = computed(() => product.value?.productName);
const memos = ref<Memo[]>([]);
const nodes = ref<Node[]>([]);
const edges = ref<Edge[]>([]);
/**节点和其坐标 */
const nodeCoordinates = ref<ProductTree.NodeLocation[]>([]);
/**组成该产品的所有材料 */
// 动态添加新节点的函数
const isModalDelOpen = ref(false); // 删除框显示
const selectedNodeType = ref(""); // 存储选择的节点类型
const InformationWindowRef = ref<InstanceType<typeof Structure_Information> | null>(null);
const OutMaterialWindowRef = ref<InstanceType<typeof OutMaterial_Information> | null>(null);
/**节点序号与materialId的映射关系 */
const indexToNodeMap = ref<Map<number, number>>(new Map());
/**以节点序号的边描述 */
const indexedEdges = ref<{ source: number; target: number }[]>([]);

// 页面加载时初始化节点和连线
onMounted(async () => {
  currentProjectId.value = route.params.projectId as string;
  await initFormData();
  initializeNodesAndEdges();
  initializeLeft();
});

/**初始化产品数据，产品结构树数据 */
const initFormData = async () => {
  try {
    const userInfo = JSON.parse(localStorage.getItem("userInfo") || "{}");
    const userId = Number(userInfo.id) || 0; // 如果没有 id，则使用默认值 0

    // 1. 首先获取产品基本信息
    const response = await axios.post(baseUrl + "/api/carbon/getProductByProjectById?projectId=" + currentProjectId.value, {
      userId: userId
    });

    if (response.data && response.data.code === 200) {
      product.value = response.data.data;

      // 2. 如果成功获取产品信息，且有产品ID，则获取产品结构树信息和所有材料信息
      if (product.value && product.value.id) {
        try {
          // 获取产品结构树数据
          const materialResponse = await axios.post(
            baseUrl +
              "/api/carbon/getMaterialsByProductId?productId=" +
              product.value.id +
              "&projectId=" +
              currentProjectId.value,
            {
              userId: userId
            }
          );

          if (materialResponse.data && materialResponse.data.code === 200) {
            materialList.value = materialResponse.data.data;
          } else {
            // 处理错误情况
            const errorMsg = materialResponse.data?.msg || "获取材料失败";
            console.error("获取材料信息错误:", errorMsg);
            ElMessage.warning(errorMsg);
          }
        } catch (materialError) {
          console.error("获取材料信息出错:", materialError);
          ElMessage.warning("获取材料信息失败");
        }
        try {
          // 获取产品结构树数据
          const treeResponse = await axios.post(baseUrl + "/api/carbon/getTreeByProductId?productId=" + product.value.id, {
            userId: userId
          });

          if (treeResponse.data && treeResponse.data.code === 200) {
            // 获取产品结构树成功，将数据保存到fetchedProductTree或对应变量
            tree.value = treeResponse.data.data;
          } else {
            // 处理错误情况
            const errorMsg = treeResponse.data?.msg || "获取产品结构树失败";
            console.error("获取产品结构树错误:", errorMsg);
            ElMessage.warning(errorMsg);
          }
        } catch (treeError) {
          console.error("获取产品结构树出错:", treeError);
          ElMessage.warning("获取产品结构树失败");
        }
      }
    } else {
      // 处理后端返回的错误信息
      const errorMsg = response.data.msg || "获取产品信息失败";
      console.error("获取产品信息错误:", errorMsg);
      ElMessage.error(errorMsg);
    }
  } catch (error) {
    console.error("获取产品信息出错:", error);
    ElMessage.error("获取产品信息失败，可能是因为参数错误或网络问题");
  }
};

/**初始化节点和连线 */
const initializeNodesAndEdges = () => {
  // 注册树中提到的所有材料
  if (!tree.value || !tree.value.node || !tree.value.edge) {
    ElMessage({
      type: "warning",
      message: "产品树为空!"
    });
    return;
  }
  // 处理特殊情况：只有根节点，没有边
  if (tree.value.edge.length === 0) {
    // 创建单独的根节点
    nodes.value = [
      {
        id: "1",
        position: { x: 0, y: 0 },
        data: {
          selected: false,
          materialID: -1,
          label: rootname.value,
          rootid: product.value.id
        },
        style: {
          background: "#fff"
        },
        type: "productNode_outBuy"
      }
    ];
    edges.value = []; // 边为空数组
    return; // 提前返回，不执行后续逻辑
  }
  const result = assignNodeIndices(tree.value.edge);
  indexToNodeMap.value = result.indexToNodeMap;
  indexedEdges.value = result.indexedEdges;
  nodeCoordinates.value = calculateNodeCoordinates(indexedEdges.value, 1, 300, 80);
  // 添加节点
  const newNodes: (Node & { selected?: boolean })[] =
    nodeCoordinates.value.map(unitnode => {
      const materialID = indexToNodeMap.value.get(unitnode.index);
      // 没找到，则产品节点
      if (materialID === -1) {
        return {
          id: String(unitnode.index),
          position: { x: unitnode.x, y: unitnode.y }, // 节点垂直排列
          data: {
            selected: false,
            materialID: -1,
            label: rootname.value,
            rootid: product.value.id
          },
          style: {
            background: "#fff"
          },
          type: "productNode_outBuy"
        };
      } else {
        const material = findMaterialInfoById(materialID)!;
        let nodeType = "";
        if (material.sourceType === 1) nodeType = "productNode_homeMade";
        else nodeType = "productNode_outBuy1";
        return {
          id: String(unitnode.index),
          position: { x: unitnode.x, y: unitnode.y }, // 节点垂直排列
          data: {
            selected: false,
            materialID: materialID,
            label: material.materialName
          },
          style: {
            background: "#fff"
          },
          type: nodeType
        };
      }
    }) || [];
  nodes.value = newNodes; // 更新节点
  // 添加边
  const newEdges: Edge[] =
    indexedEdges.value.map((unitnode, index) => {
      return {
        id: (index + 1).toString(),
        source: unitnode.source.toString(),
        target: unitnode.target.toString(),
        markerEnd: {
          type: MarkerType.ArrowClosed,
          color: "#999999"
        }
      };
    }) || [];
  // 更新 edges.value
  edges.value = newEdges;
};

/**
 * 返回材料在tree.value.node中的信息
 * @param id 材料id
 */
function findMaterialInfoById(id: number | undefined) {
  if (id === undefined) return undefined;
  if (!tree.value || !tree.value.node) return undefined;
  return tree.value.node.find(material => material.id === id);
}
/**
 * 盒子的点击事件
 * @param memo 左边的节点列表
 */
function handleMemoClick(memo: Memo) {
  console.log("Memo clicked:", memo);
  // 在这里添加您希望在点击时执行的操作
}

/**初始化左边的外购物料信息 */
function initializeLeft() {
  memos.value = []; // 先清空
  materialList.value?.map(material => {
    // 判断是否是外购件
    if (material.sourceType === 2) {
      if (material.status === 0)
        memos.value.push({
          name: material.materialName || "",
          status: "🧐未申请",
          button: "申请PCF",
          materialId: material.id || -1
        });
      else if (material.status === 1)
        memos.value.push({
          name: material.materialName || "",
          status: "⏳正在审核",
          button: "取消申请",
          materialId: material.id || -1
        });
      else if (material.status === 2)
        memos.value.push({
          name: material.materialName || "",
          status: "✅申请通过",
          button: "查看详情",
          materialId: material.id || -1
        });
      else
        memos.value.push({
          name: material.materialName || "",
          status: "❌申请失败",
          button: "重新申请",
          materialId: material.id || -1
        });
    }
  });
}

const goToPreviousStep = () => {
  if (route.meta.isAffix) return;
  tabStore.removeTabs(route.fullPath);
  router.push(`/lca/inventory/activityList/${currentProjectId.value}`);
};
/**下一步跳转 */
const goToNextStep = () => {
  if (route.meta.isAffix) return;
  tabStore.removeTabs(route.fullPath);
  router.push(`/lca/inventory/materialIndex/${currentProjectId.value}`);
};

/**管理按钮事件 */
async function handleMemo(memo: Memo) {
  console.log("memo:", memo);
  try {
    const userInfo = JSON.parse(localStorage.getItem("userInfo") || "{}");
    const userId = Number(userInfo.id) || 0;
    // 获取产品基本信息
    const response = await axios.post(
      baseUrl +
        "/api/carbon/getOutPCFDataByProjectAndMaterial?projectId=" +
        currentProjectId.value +
        "&materialId=" +
        memo.materialId,
      {
        userId: userId
      }
    );

    if (response.data && response.data.code === 200) {
      let PCF = response.data.data;
      console.log("PCF:", PCF);
      if (PCF.status === 2) openOutMaterialWindow(PCF);
      else if (PCF.status === 0 || PCF.status === 3) {
        const response = await axios.post(
          baseUrl + "/api/carbon/createPCFrequest?projectId=" + currentProjectId.value + "&materialId=" + memo.materialId,
          {
            userId: userId
          }
        );
        if (response.data && response.data.code === 200) {
          // 获取MPpair信息
          materialList.value.find(node => node.id === memo.materialId)!.status = 1;
          initializeLeft();
          ElMessage({
            type: "success",
            message: "申请成功!"
          });
        } else {
          const errorMsg = response.data.msg || "申请失败";
          console.error("申请材料信息错误:", errorMsg);
          ElMessage.error(errorMsg);
        }
      } else if (PCF.status === 1) {
        ElMessageBox.confirm("是否撤销申请?", "温馨提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
          draggable: true
        }).then(async () => {
          // 撤销申请
          const response = await axios.post(
            baseUrl + "/api/carbon/revokePCFrequest?projectId=" + currentProjectId.value + "&materialId=" + memo.materialId,
            {
              userId: userId
            }
          );
          if (response.data && response.data.code === 200) {
            // 修改材料状态
            materialList.value.find(node => node.id === memo.materialId)!.status = 0;
            initializeLeft();
            ElMessage({
              type: "success",
              message: "撤销成功!"
            });
          } else {
            const errorMsg = response.data.msg || "撤销申请失败";
            console.error("撤销申请错误:", errorMsg);
            ElMessage.error(errorMsg);
          }
        });
      }
    } else {
      // 处理后端返回的错误信息
      const errorMsg = response.data.msg || "获取材料信息失败";
      console.error("获取材料信息错误:", errorMsg);
      ElMessage.error(errorMsg);
    }
  } catch (error) {
    console.error("获取材料信息出错:", error);
    ElMessage.error("获取材料信息失败，可能是因为参数错误或网络问题");
  }
}

/**
 * 节点点击事件
 * @param node 点击节点内容
 */
function onNodeClick(node: any) {
  console.log(node);
}

const closeDelModal = () => {
  isModalDelOpen.value = false;
  selectedNodeType.value = ""; // 清空选择
};

const deleteNode = () => {
  // 找到要删除的节点
  const selectedNode = nodes.value.find(node => node.selected);
  if (!selectedNode) {
    ElMessage({
      type: "warning",
      message: "请选择一个物料!"
    });
    return;
  }
  let id = selectedNode.id;
  if (selectedNode.id == "1") {
    ElMessage({
      type: "warning",
      message: "产品节点不能删除!"
    });
    return;
  }
  const nodeIndex = nodes.value.findIndex(node => node.id === id);
  // 删除节点
  nodes.value.splice(nodeIndex, 1);
  // 删除与该节点相关的边
  edges.value = edges.value.filter(edge => edge.source !== id && edge.target !== id);
  // 关闭模态框
  closeDelModal();
};

const openInformWindow = (nodeid: string, source: number) => {
  if (InformationWindowRef.value) {
    InformationWindowRef.value.openDialog(nodeid, source);
  }
};
const openOutMaterialWindow = (PCF: any) => {
  if (OutMaterialWindowRef.value) {
    OutMaterialWindowRef.value.openDialog(PCF);
  }
};

/**
 * 按下toolBar按钮的处理函数
 */
const handleToolbarAction = (action: string, materialId: string, source: number) => {
  if (action === "详情") openInformWindow(materialId, source);
  else {
    ElMessageBox.confirm("是否删除所选项?", "温馨提示", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
      draggable: true
    }).then(() => {
      deleteNode(); // 调用删除逻辑
      ElMessage({
        type: "success",
        message: "删除成功!"
      });
    });
  }
};
</script>

<style lang="scss">
.sidebar {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: 15px;
  width: 20%;
  min-width: 180px;
  max-width: 300px;
  padding: 20px;
  overflow-y: auto;
  background-color: #f4f6f8;
  border-right: 1px solid #e0e0e0;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgb(0 0 0 / 10%);
}

/* 侧边栏卡片内容 */
.sidebar .memo-item {
  padding: 12px 16px;
  margin-bottom: 3px; /* 每个条目之间的间隔 */
  cursor: pointer;
  background-color: #ffffff;
  border: 1px solid #dddddd;
  border-radius: 8px;
  box-shadow: 0 2px 5px rgb(0 0 0 / 10%);
  transition: background-color 0.3s;
}
.sidebar .memo-item:hover {
  background-color: #e6f5f3;
}
.sidebar .memo-name {
  margin-bottom: 10px; /* Name与下方内容的间隔 */
  font-size: 16px;
  font-weight: bold;
}
.sidebar .memo-content {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.sidebar .memo-status {
  flex: 1;
  padding-right: 10px;
  font-size: 14px;
}
.sidebar .memo-button {
  padding: 6px 12px;
  color: white;
  cursor: pointer;
  background-color: #009688;
  border: none;
  border-radius: 5px;
  transition: background-color 0.3s;
}
.sidebar .memo-button:hover {
  background-color: #007d6a;
}
.flow-container {
  position: relative;
  flex: 1;
  overflow: hidden;
}
.steps-container {
  display: flex;
  justify-content: space-between;
  width: 80%;
  padding: 0 20px;
}
.step-box {
  position: relative;
  flex: 1;
  padding: 15px 10px;
  margin: 0 10px;
  text-align: center;
  cursor: pointer;
  background-color: #f9f9f9;
  border: 1px solid #dcdcdc;
  border-radius: 5px;
  transition: all 0.3s;
}

// 激活状态
.step-box.active {
  font-weight: bold;
  color: #009688;
  background-color: #e6f5f3;
  border-color: #009688;
}

// 步骤框之间的箭头
.step-box::after {
  position: absolute;
  top: 50%;
  right: -20px;
  font-size: 20px;
  color: #009688;
  content: "→";
  transform: translateY(-50%);
}
.step-box:last-child::after {
  visibility: hidden;
}
.nav-button {
  padding: 10px 20px;
  font-size: 16px;
  color: white;
  cursor: pointer;
  background-color: #009688;
  border: none;
  border-radius: 5px;
  transition: background-color 0.3s;
  &:hover {
    background-color: #007d6a;
  }
}
.header {
  display: flex;
  align-items: center;
  justify-content: space-between; /* 左右分布 */
  padding: 10px 20px;
  background-color: #ffffff;
  border-bottom: 1px solid #dddddd;
  border-radius: 8px;
}
.header-buttons {
  display: flex;
  gap: 10px; /* 按钮之间的间距 */
  margin-left: auto; /* 将按钮推到最右侧 */
}
.back-button {
  padding: 8px 12px;
  margin-right: 20px;
  font-size: 14px;
  color: white;
  cursor: pointer;
  background-color: #009688;
  border: none;
  border-radius: 4px;
  transition: background-color 0.2s ease;
}
.back-button:hover {
  background-color: #007d6a;
}
.title {
  font-size: 18px;
  font-weight: bold;
  color: #333333;
}
.modal {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background: rgb(0 0 0 / 50%);
}
.modal-content {
  z-index: 9999;
  width: 400px;
  max-width: 90%;
  padding: 20px;
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgb(0 0 0 / 10%);
}
select {
  z-index: 10000;
  width: 100%;
  padding: 8px;
  margin: 10px 0;
  border: 1px solid #cccccc;
  border-radius: 4px;
}
button {
  padding: 8px 12px;
  margin: 5px;
  color: white;
  cursor: pointer;
  background-color: #009688;
  border: none;
  border-radius: 4px;
}
button:hover {
  background-color: #009688;
}
.customNode {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100px;
  height: 50px;
  cursor: pointer;
  border: 1px solid #cccccc;
  border-radius: 4px;
}
.customNode.selected {
  color: white;
  background-color: #4caf50;
}
.vue-flow__node-toolbar {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  padding: 8px;
  background-color: #2d3748;
  border-radius: 8px;
  box-shadow: 0 0 10px rgb(0 0 0 / 50%);
}
.vue-flow__node-toolbar button {
  padding: 0.5rem;
  color: white;
  cursor: pointer;
  background: #4a5568;
  border: none;
  border-radius: 8px;
}
.vue-flow__node-toolbar button.selected {
  background: #009688;
}
.vue-flow__node-toolbar button:hover {
  background: #009688;
}
.vue-flow__node-productNode_homeMade {
  padding: 20px 24px;
  color: #009688;
  background: #e6f5f3;
  border: 1px solid #009688;
  border-radius: 4px;
  box-shadow: 0 0 10px rgb(0 0 0 / 20%);
}
.vue-flow__node-productNode_homeMade.selected {
  border: 1px solid red;
}
.vue-flow__node-productNode_outBuy {
  padding: 20px 24px;
  color: #009688;
  background: #e6f5f3;
  border: 1px solid #009688;
  border-radius: 4px;
  box-shadow: 0 0 10px rgb(0 0 0 / 20%);
}
.vue-flow__node-productNode_outBuy.selected {
  border: 1px solid red;
}
.vue-flow__node-productNode_outBuy1 {
  padding: 20px 24px;
  color: #009688;
  background: #e6f5f3;
  border: 1px solid #009688;
  border-radius: 4px;
  box-shadow: 0 0 10px rgb(0 0 0 / 20%);
}
.vue-flow__node-productNode_outBuy1.selected {
  border: 1px solid red;
}
</style>
